#include"main.h"

//初始化
int init_stack(Stack *s){
    (*s) = malloc(sizeof (struct stack));
    int *p =(int *) malloc(sizeof((*s)->base) *STACK_MAX_SIZE);
    (*s)->base = p;
    if(!(*s)->base){
        printf("错误");
        return 1;
    }

    (*s)->top = (*s)->base;
    (*s)->number_of_elements = 0;
    return 0;
}
//字符转换为数字
int chTurnInt(char operator){
    switch (operator) {
        case '0':return 0;
        case '1':return 1;
        case '2':return 2;
        case '3':return 3;
        case '4':return 4;
        case '5':return 5;
        case '6':return 6;
        case '7':return 7;
        case '8':return 8;
        case '9':return 9;
    }
    return 0;
}

//操作符判断
bool is_operator(char symbol){
    if(symbol =='+' || symbol == '-' || symbol == '/' || symbol == '*' || symbol == '(' || symbol == ')' || symbol == '#')return 1;
    return 0;
}
//操作数字判断
bool is_operand(char symbol){
    if (symbol<= '9' && symbol >= '1')return 1;
    return 0;
}
//入栈
int push(Stack s, char operator_or_operand){
    if(s->top-s->base == STACK_MAX_SIZE){
        return 1;
    }
    if(is_operator(operator_or_operand))
    {
        *(s->top) = operator_or_operand;
    } else if(is_operand(operator_or_operand)){
	//用chTurnInt进行字符与数字的转换，再入栈
        *(s->top) = chTurnInt(operator_or_operand);
    } else{
	
	*(s->top) = operator_or_operand;
	
    }
    s->top++;
    s->number_of_elements++;
    return 0;
};
//出栈
int pop(Stack s, char * p_operator_or_operand){
    if(s->top == s->base){
        return 0;
    }
    --s->top;
    *p_operator_or_operand = *(s->top);
    s->number_of_elements--;
    return 1;
}
//返回栈顶元素
int get_top(Stack s, char * symbol){
    if(s->base == s->top){
        return 1;
    }
    *symbol = *(s->top-1) ;
    return 0;

}
//判断优先
char compare(char a ,char b){
    char sign=' ';

    if(a == '-' || a == '+'){
        if(b == '+' || b == '-'  || b == ')' || b == '#')
        {
			return sign = '>';
		}
        else
        {
			return sign = '<';
		}
    } else if(a == '*' || a == '/' ){
        if(b == '(')
        {
			return sign = '<';
		}
        else{
			return sign = '>';
		}
    } else if(a == '('){
        if (b == ')')
        {
			return sign = '=';
		}
        else if(b == '#'){
            return 'f';
		}
        else{
            return sign = '<';
		}
    } else if (a == ')'){
        if(b == '('){
            return 'f';
        } else{      
            return sign = '>';
		}
    } else if (a == '#'){
        if(b == ')'){
            return 'f';
        } else if(b == '#')
        {
            return sign = 'y';
		}
        else{
            return sign = '<';
        }
    }
    return 'f';
}

int operation(int a,int b,char c){
    switch (c) {
        case '+':return a+b;
        case '-':return a-b;
        case '*':return a*b;
        case '/':return a/b;
    }
    return 0;
}

// 用于计算表达式的值，比如#3*(2+6)/4#。
// 返回值表示求值状态：0，合法表达式，成功求值；1，表达式不合法。
// result变量用于返回计算结果。
int evaluate(char * expression, int * result){
    Stack s1;//存放数字
    Stack s2;//存放操作符
	
    char a;//存放出栈元素
    char b;
	
    int aNum;
    int bNum;
	
    char symbol;//存放返回的栈顶元素
    char ch;//存放数字和操作符的临时变量
    char oper;
	
	//初始化栈
    init_stack(&s1);
    init_stack(&s2);
	
	//入栈（第一个元素入栈）
    push(s2,*expression);
	
	//进行下一个
    ch = *(++expression);
    while (1){
	
	//是否为数字
        if(is_operand(ch)){
		//数字入栈
            push(s1,ch);
        }
		//是否为操作符
        else if(is_operator(ch)){
		//获取栈顶元素
            get_top(s2,&symbol);
			
            switch (compare(symbol,ch)) {
                case '>':
                    pop(s1,&a);		//a先获得出栈元素
                    aNum = (int)a;
					
                    pop(s1,&b);		//b再获得a出栈之后的下一个元素
                    bNum = (int) b;
					
                    pop(s2,&symbol);//后出栈元素在前（栈先入后出）
                    oper =(char) operation(bNum,aNum,symbol);
					
                    push(s1, oper);//将计算结果再压栈
                    get_top(s2,&symbol);
					
                    expression--;
                    break;
                case '<':
                    push(s2,ch);
                    break;
                case '=':
                    pop(s2,&symbol);
                    get_top(s2,&symbol);
                    break;
                case 'f':
                    printf("表达式有错误");return 1;
            }
        } else{
            break;
        }
        ch = *(++expression);
    }

    get_top(s1,&symbol);
    *result =symbol;
    return 1;
}

//测试代码
int main(){
    char *expression = "#3*(2+6)/4#";
    int result = 0;
    if(evaluate(expression,&result)){
        printf("结果是 = %d\n",result);
    }
}